#include <stdlib.h>
#include <curses.h>
#include <math.h>
#include "game.h"
#include "ball.h"
#include "player.h"
#include "field.h"



void add_ball(FIELD* f, int max_value) {
	POINT* playerhead = f -> player -> body[f -> player -> head_ptr];
	BALL* b = malloc(sizeof(BALL));
	
	//find a value
	int value = (random() % max_value) + 1;
	
	//get random position that's at least 10 away from the player's head
	int x;
	int y;
	int dir = random() % 4;
	do {
		x = (random() % (f -> width - 2)) + 1;
		y = (random() % (f -> height - 2)) + 1;
		
	} while (sqrt((double)((x - playerhead -> x) * (x - playerhead -> x) +
		(y - playerhead -> y) * (y - playerhead -> y))) < (double) (13 + value));
	
	init_ball(b, x, y, dir, value);
	f -> ball_count++;
	
	
	//if ball buffer is too small, double it
	if (f -> ball_count >= f -> max_allocated_balls) {
		f -> max_allocated_balls *= 2;
		f -> balls = realloc(f -> balls, f -> max_allocated_balls);
	}
	f -> balls[f -> ball_count - 1] = b;
}

void init_field(FIELD* f, int width, int height, GAME_STATE* state) {
	f -> state = state;
	f -> win = subwin(stdscr, height, 2 * width, 0, 0);
	f -> width = width;
	f -> height = height;
	f -> max_allocated_balls = 1;
	f -> balls = malloc(sizeof(BALL) * f -> max_allocated_balls);
	f -> ball_count = 0;
	f -> player = malloc(sizeof(PLAYER));
}

void destroy_field(FIELD* f) {
	destroy_player(f -> player);
	for (int i = 0; i < f -> ball_count; i++) {
		free(f -> balls[i]);
	}
	
	free(f -> balls);
	delwin(f -> win);
	free(f);
}


void draw_outline(FIELD* f) {
	wattrset(f -> win, COLOR_PAIR(1));
	for (int i = 0; i < f -> width * 2 - 1; i++) {
		mvwprintw(f -> win, 0, i , "  ");
		mvwprintw(f -> win, f -> height - 1, i , "  ");
	}
	for (int i = 1; i < f -> height - 1; i++) {
		mvwprintw(f -> win, i, 0 , "  ");
		mvwprintw(f -> win, i,  f -> width * 2 - 2, "  ");
	}
}


void draw_player(FIELD* f) {
	wattrset(f -> win, COLOR_PAIR(2));
	PLAYER* player = f -> player;
	POINT* p;
	for (int i = 0; i < player -> length; i++) {
		p = player -> body[i];
		mvwprintw(f -> win, p -> y, p -> x * 2, "  ");
	}
}

void redraw_field(FIELD* f) {
	clear();
	wattrset(f -> win, COLOR_PAIR(1));
	draw_outline(f);
	
	for (int i = 0; i < f -> ball_count; i++) {
		BALL* b = f -> balls[i];
		wattrset(f -> win, COLOR_PAIR(b -> color));
		mvwprintw(f -> win, b -> position.y, b -> position.x * 2, "  ");
	}
	draw_player(f);
	wrefresh(f -> win);
}

void update_ballpos(FIELD* f) {
	for (int i = 0; i < f -> ball_count; i++) {
		BALL* b = f -> balls[i];
		// clear old ball position if it's not on player
		if (! is_on_player(f -> player, & b -> old_position)) {
			wattrset(f -> win, COLOR_PAIR(7));
			mvwprintw(f -> win, b -> old_position.y, b -> old_position.x * 2, "  ");
		}
		// draw ball at new position
		wattrset(f -> win, COLOR_PAIR(b -> color));
		mvwprintw(f -> win, b -> position.y, b -> position.x * 2, "  ");
	}
	wrefresh(f -> win);
}
void update_playerpos(FIELD* f) {
	PLAYER* player = f -> player;
	wattrset(f -> win, COLOR_PAIR(7));
	mvwprintw(f -> win, player -> old_tail -> y, player -> old_tail -> x * 2, "  ");
	wattrset(f -> win, COLOR_PAIR(2));
	mvwprintw(f -> win,
			player -> body[player -> head_ptr] -> y,
			player -> body[player -> head_ptr] -> x * 2,
			"  ");
	wrefresh(f -> win);
}
